//
//  NSString+ZUtilities.m
//  WeClubs
//
//  Created by Zed Link on 30/3/2017.
//  Copyright © 2017 Zed. All rights reserved.
//

#import "NSString+ZUtilities.h"
#import <CommonCrypto/CommonDigest.h>

@implementation NSString (ZUtilities)

#pragma mark - 数据加密相关

- (NSString *)zSHA1String
{
    // 中文时会丢失数据
//    const char *cStr = [self cStringUsingEncoding:NSUTF8StringEncoding];
//    NSData *data = [NSData dataWithBytes:cStr length:self.length];
    
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    
    uint8_t result[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(data.bytes, (unsigned int)data.length, result);
    
    NSMutableString *hex = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
    for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) {
        [hex appendFormat:@"%02X", result[i]];
    }
    return hex;
}

- (NSString *)zMD5BiaryString
{
    const char *cStr = [self UTF8String];
    uint8_t result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cStr, (unsigned int)strlen(cStr), result);
    
    NSMutableString *binary = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [binary appendFormat:@"%d", (char)result[i]];
    }
    return binary;
}

- (NSString *)zMD5HexString
{
    /**
     MD5是长度为128位, 占16个字节大小, 用32个16进制数表示(一个16进制数占4位)
     一个字节能存储2个16进制数, 当结果不足2位时, 避免丢失该16进制值, 需要补0
     */
    
    const char *cString = [self UTF8String];
    uint8_t result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cString, (unsigned int)strlen(cString), result);
    
    NSMutableString *hex = [NSMutableString string];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        // 不足两位，前面补0, 16进制输出
        [hex appendFormat:@"%02X", result[i]];
    }
    
    NSString *MD5String = [hex lowercaseString];
    return MD5String;
}

#pragma mark - 正则表达式相关

- (BOOL)zCheckPhoneNumber
{
    // ^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8}$
    NSString *pattern = @"^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8}$";
    NSString *substring = [self firstSubstringWithPattern:pattern];
    
    if (substring == nil) {
        return NO;
    } else {
        ZLog(@"手机号验证正确: %@", substring);
        return YES;
    }
}

// 没有匹配结果时, 返回 NSMakeRange(NSNotFound, 0)
- (NSRange)firstRangeWithPattern:(NSString *)pattern
{
    NSError *error;
    NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
    if (error) {
        ZLog(@"正则表达式创建失败: %@", error);
        return NSMakeRange(NSNotFound, 0);
    }
    
    NSTextCheckingResult *result = [regular firstMatchInString:self options:0 range:NSMakeRange(0, self.length)];    
    return result.range;
}

// 没有匹配结果时, 返回 nil
- (NSString *)firstSubstringWithPattern:(NSString *)pattern
{
    NSRange firstRange = [self firstRangeWithPattern:pattern];
    if (firstRange.location == NSNotFound || firstRange.length == 0) {
        return nil;
    }
    
    return [self substringWithRange:firstRange];
}

// 没有匹配结果时, 返回nil; 有结果时返回包装了NSRange的NSValue数组
- (NSArray <NSValue *> *)matchRangesWithPattern:(NSString *)pattern
{
    NSError *error;
    NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
    if (error) {
        ZLog(@"正则表达式创建失败: %@", error);
        return nil;
    }
    
    NSArray <NSTextCheckingResult *> *results = [regular matchesInString:self options:0 range:NSMakeRange(0, self.length)];
    if (results.count == 0 || results == nil) {
        ZLog(@"没有匹配的结果: %@", error);
        return nil;
    }
    
    NSMutableArray *ranges = [NSMutableArray arrayWithCapacity:results.count];
    for (NSTextCheckingResult *result in results) {
        NSValue *rangeValue = [NSValue valueWithRange:result.range];
        [ranges addObject:rangeValue];
    }
    return ranges;
}

// 没有匹配结果时, 返回nil; 有结果时返回NSString数组
- (NSArray <NSString *> *)matchSubstringsWithPattern:(NSString *)pattern
{
    NSArray <NSValue *> *results = [self matchRangesWithPattern:pattern];
    if (results == nil || results.count == 0) {
        return nil;
    }
    
    NSMutableArray *substrings = [NSMutableArray arrayWithCapacity:results.count];
    for (NSValue *value in results) {
        NSString *substring = [self substringWithRange:value.rangeValue];
        [substrings addObject:substring];
    }
    return substrings;
}

@end
